#include "GameplayController.h"

#include "windows.h"
#include <iostream>

#include <boost/bind.hpp>
#include "AccusationController.h"
#include "BoardController.h"
#include "CardsDealController.h"
#include "DeductionController.h"
#include "../domain/configuration/CardsConfiguration.h"
#include "../domain/models/Card.h"
#include "../domain/models/CardsCollection.h"
#include "../views/DependencyContainer.h"
#include "../views/concrete/console/BoardView.h"

using namespace Controllers;

GameplayController::GameplayController(): winner(NULL), turn_controller(NULL)
{
	Domain::Configuration::CardsConfiguration cards_configuration;
	Cards::PlayersCards players_cards = cards_configuration.createPlayersCards();
	Cards::WeaponsCards weapons_cards = cards_configuration.createWeaponsCards();
	Cards::RoomsCards rooms_cards = cards_configuration.createRoomsCards();
	cards = Cards::CardsCollection(players_cards, weapons_cards, rooms_cards);

	Views::DependencyContainer::initialize(this);
	view = Views::DependencyContainer::getInstance()->getGameplayViewInstance();
}

void GameplayController::startGame()
{
	pickPlayers();
	searched_cards = CardsDealController(players, cards).perform();

	while(!isGameEnded()) 
	{
		startRound();
		Players::Player* starting_player = players.front();
		do {
			current_player = players.front();
			makeTurn();
			players.pop();
			players.push(current_player);
		} while (current_player != starting_player && !isGameEnded());
		endRound();
	}
}

void GameplayController::makeTurn()
{
	std::cout << "Tura gracza " << current_player->getName() << std::endl;

	delete turn_controller;
	turn_controller = new TurnController(current_player, players, cards, searched_cards);
	connectEvent<void ()>(turn_controller->gameWinEvent, boost::bind(&GameplayController::onGameWin, this));
	turn_controller->begin();
}

void GameplayController::pickPlayers()
{
	std::queue<Cards::PlayerCard*> p_cards = view->openPickPlayersDialog();
	while(!p_cards.empty())
	{
		Players::Player* player = new Players::Player(p_cards.front()->getTitle(), p_cards.front()->getPiece(), Cards::CardSet());
		players.push(player);
		p_cards.pop();
	}
}

void GameplayController::startRound()
{
}

void GameplayController::endRound()
{
}

void GameplayController::onGameWin()
{
	winner = current_player;
}

bool GameplayController::isGameEnded()
{
	return winner != NULL;
}

Players::PlayersQueue GameplayController::getPlayers()
{
	return players;
}

Cards::PlayersCards GameplayController::getPlayersCards()
{
	return cards.getPlayersCards();
}

Cards::RoomsCards GameplayController::getRoomsCards()
{
	return cards.getRoomsCards();
}


